/**  \file main.qml
\brief Main QML file

Price My House for Nokia mobile platforms.

WARNING: the text content of all the visual elements refers to the DataItem object
instantiated by the HouseProfile class. If this object is not created in the application
none of the text values are shown in the application.

\author © 2011 Enrico Miglino / Tech Consulting (enrico.miglino@ovi.com)
\author "Evimin Fiyati Price My House" is protected by the copyright law
\author Distributed under the LGPL 3.0 license.
\date 2011

\par Licensing notes

    "Price My House" is free software: you can redistribute it
    and/or modify it under the terms of the Lesser GNU General Public License
    as published by the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.

    "Price My House" is distributed in the hope that it
    will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    Lesser GNU General Public License for more details.

    You should have received a copy of the Lesser GNU General Public License
    along with "Price My House".
    If not, see <http://www.gnu.org/licenses/>.

*/

import QtQuick 1.0
//import com.nokia.symbian 1.0
import AppJson 1.0
// Qt-Complex objecs and functions
import "Qt-Complex" as Framework
import "Qt-Complex/Theme.js" as JTheme
import "Qt-Complex/Geometry.js" as Geometry
// Dedicated components for the main application
import "elements" as PriceMyHouse
import "house" as MyHouse
import "elements/PriceMyHouse.js" as Jmain

MyHouse.DataItem {
    id: appItem

    width: screen.displayWidth
    height: screen.displayHeight

    signal jsonPropertiesReady

    // When finishes loading the component assign the properties to the loaders
    Component.onCompleted: {
        viewmapLoader.obj = "MapView";
        infoLoader.obj = "Info";
        btnNewUser.obj = "MessageBox";
        toolbarLoader.obj = "ToolBar";
        topbannerLoader.obj = "StaticBanner";
        left.obj = "ButtonIcon";
        showAll.obj = "Button";
        right.obj = "ButtonIcon";
        console.log("*** DataItem finished loading: assigned the objects to the loaders.")
    }

    // Initializes application data object
    // When this object is instantiated its properties are set pointing to the global (internal)
    // configuration file. The same instance is reused for the program data fields and combo boxes.
    // AppData is a object returning a json text content data stream based on file and folder properties
    // Optionally can be set a language code.
    AppData {
        id: dataParameters

        signal updateJson
        signal updateProperties

        // Set the application root file name. The global file name has no localization
        // information (valid for all applicaiton languages).
        fname: Jmain.rootFile;
        language: ""    // json global configuration file should not be localized
        // Set the folder name where configuration files are stored
        folder: Jmain.configFolder
        // Generate the json decoded structure
        Component.onCompleted: {
            createConfFile();           // Create the file name
            getJson();                  // Load the json file
            Jmain.processJsonConfData();
        }
        // When this signal is fired it is requested a new datastream
        // loaded from some configuration file.
        // Assign the defaul language for the application.
        onUpdateJson: {
            createConfFile();           // Create the file name
            getJson();                  // Load the json file
            Jmain.processJsonConfData();
        }
        onUpdateProperties: appItem.jsonPropertiesReady();
    }

    // Test Component
    WebJson {
        id: jsonQueries
    }

    Framework.ComplexItem {
        id: qtComplex
        theme: appItem._theme
        screenCategory: screen.displayCategory;
    }

    // Update the application properties with the loaded parameters
    // from the json object. This signal is managed by the loader/parser function.
    // to avoid loading object parameters when the data file is not yet parsed.
    // Using the parameters object instead of a direct assignement the changes affect
    // the objects binding properties and are automatically updated.
    onJsonPropertiesReady: {
        Jmain.setMainProperties();
        Jmain.setHouseProperties();
    }

    // Map view object with navigaton controls
    Item {
        id: viewmap
        width: appItem.width;
        height: appItem.height - basebuttons.height - appTopBanner.height
        anchors.top: appTopBanner.bottom
        state: "Hide"

        // Map view object with navigaton controls
        Framework.MapLoader {
            id: viewmapLoader
            width: viewmap.width; height: viewmap.height;
            theme: _theme
            obj: "" // "MapView"
        }
        states: [
            State { name: "Show"; AnchorChanges { target: viewmap; anchors.left: appItem.left } },
            State { name: "Hide"; AnchorChanges { target: viewmap; anchors.left: appItem.right } }
        ]
        transitions: Transition {
            AnchorAnimation { duration: Jmain.animDuration; easing.amplitude: 1; easing.type: Easing.OutQuad }
        }
    }

    // Application background
    Rectangle {
        id: background

        width: appItem.width
        height: appItem.height
        color: "black"
    }

    // Disclaimer web page
    Item {
        id: disclaimer
        width: parent.width
        height: parent.height - appTopBanner.height - basebuttons.height
        anchors.top: appTopBanner.bottom

        Flickable {
            id: flickDisclaimer

            clip: true
            anchors.fill: parent
            contentWidth: parent.width;
            contentHeight: disclaimerpage.height

            PriceMyHouse.Disclaimer {
                id: disclaimerpage
                linkedUrl: appItem._disclaimerURL
            }
        }
    }

    // Info page
    Rectangle {
        id: infopage

        width: parent.width
        height: parent.height - appTopBanner.height - basebuttons.height
        color: Jmain.appBackground
        anchors.top: appTopBanner.bottom
        state: "Hide"

        Flickable {
            id: flickInfo
            clip: true
            anchors.fill: infopage;
            contentWidth: infopage.width;
            contentHeight: infoLoader.height

            Framework.Loader {
                id: infoLoader
                width: Math.round(infopage.width * 0.95);
                height: Math.round(infopage.height * 1.30);
                anchors.horizontalCenter: parent.horizontalCenter
                theme: appItem._theme;
                obj: "" // "Info";
                obj_string: appItem.info_txt1;
                obj_message: appItem.info_txt2;
            }
        }

        states: [
            State {
                name: "Show"
                AnchorChanges { target: infopage; anchors.left: parent.left }
            },
            State {
                name: "Hide"
                AnchorChanges { target: infopage; anchors.left: parent.right }
            }
        ]

        transitions: Transition {
            AnchorAnimation {
                duration: Jmain.animDuration
                easing.amplitude: 1; easing.type: Easing.OutQuad }
        }
    }

    // House profile page
    MyHouse.HouseProfile  {
        id: formsprofile

        width: parent.width
        height: parent.height - appTopBanner.height - navButtons.height
        anchors.top: appTopBanner.bottom
        state: "Hide"

        states: [
            State {
                name: "Show"
                AnchorChanges {
                    target: formsprofile;
                    anchors.top: appTopBanner.bottom
                    anchors.bottom: undefined
                }
            },
            State {
                name: "Hide"
                AnchorChanges {
                    target: formsprofile;
                    anchors.top: undefined
                    anchors.bottom: parent.top
                }
            }
        ]

        transitions: Transition {
            AnchorAnimation {
                duration: Jmain.animDuration
                easing.amplitude: 1; easing.type: Easing.OutQuad
            }
        }
    }

    // Login form
    Rectangle {
        id: loginUser
        color: Jmain.appBackground
        width: parent.width;
        height: appItem.height - appTopBanner.height - basebuttons.height;
        anchors.top: appTopBanner.bottom
        opacity:  0
        property bool formShown: false     // Change state when login form should be shown
        property bool formHidden: false    // Change state when login form should be hidden

        // The flickable content heigt is bound to the height of the object but is not
        // set initially. The height of the object id dinamically calculated at runtime.
        Flickable {
            id: flickLogin
            clip: true
            anchors.fill: parent;
            contentWidth: parent.width;
            contentHeight: loginUserComponent.height

            // Login / New user request form
            PriceMyHouse.Login {
                id: loginUserComponent
                width: parent.width
                loginIntro: appItem.login_intro
                labelUser: appItem.login_txt1
                labelPassword: appItem.login_txt2
                buttonLogin: appItem.login_txt3
                buttonNewUser: appItem.login_txt4
                // height: Math.round(Geometry.getFieldHeight() * 9);
                onLoginClicked: Jmain.setProgramState();
                onNewuserClicked: Jmain.showNewUser();
            }
        }

        Behavior on formShown {
            NumberAnimation { target: loginUser; property: "opacity"; to: 1; duration: Jmain.animDuration }
        }
        Behavior on formHidden {
            NumberAnimation { target: loginUser; property: "opacity"; to: 0; duration: Jmain.animDuration }
        }
    }

    // New user form
    Rectangle {
        id: createUser
        color: Jmain.appBackground
        width: parent.width;
        height: appItem.height - appTopBanner.height - basebuttons.height;
        anchors.top: appTopBanner.bottom
        state:  "exitNewUser"

        Flickable {
            id: flickNewUser
            clip: true
            anchors.fill: parent;
            contentWidth: parent.width;
            contentHeight: createUserLoader.height

            PriceMyHouse.NewUser {
                id: createUserLoader
                width: parent.width
                height: Geometry.getButtonHeight() + (Geometry.getFormBorder() * 2)
                        + (Geometry.getFieldHeight() * 6);
                opacity:  1
                labelUser: appItem.login_txt1
                labelPassword: appItem.login_txt2
                buttonCreate: appItem.login_txt5
                onNewuserClicked: Jmain.confirmNewUser();
            }
        }
        states: [
            State {
                name: "enterNewUser"
                AnchorChanges { target: createUser; anchors.left: appItem.left } },
            State {
                name: "exitNewUser"
                AnchorChanges { target: createUser; anchors.left: appItem.right } }
        ]

        transitions: Transition {
            AnchorAnimation {
                duration: Jmain.animDuration
                easing.amplitude: 1; easing.type: Easing.OutQuad }
        }
    }

    // Confirm new user creation
    Item {
        id: newuserok

        width: appItem.width;
        height: appItem.height - appTopBanner.height - basebuttons.height;
        anchors.topMargin: Geometry.getFormBorder() * 2;
        signal clicked
        property alias destroyNewUserOk: btnNewUser.obj

        state: "exitNewUserConfirm"
        Rectangle { id: msgBoxBackground; color: Jmain.appBackground;
            width: parent.width; height: parent.height }

        Framework.Loader {
            id: btnNewUser
            width: Math.round(parent.width * 0.95); height: Math.round(parent.height * 0.73);
            anchors.horizontalCenter: parent.horizontalCenter
            anchors.verticalCenter: parent.verticalCenter
            theme: appItem._theme;
            obj: "" // "MessageBox";
            obj_string: appItem.login_txt6
            obj_message: appItem.login_txt7
            onClicked: { newuserok.clicked() }
        }

        // Out state definition, managed by the animation transition
        states: [
            State {
                name: "enterNewUserConfirm"
                AnchorChanges { target: newuserok; anchors.left: appItem.left } },
            State {
                name: "exitNewUserConfirm"
                AnchorChanges { target: newuserok; anchors.left: appItem.right } }
        ]

        transitions: Transition {
            AnchorAnimation {
                duration: Jmain.animDuration
                easing.amplitude: 1; easing.type: Easing.OutQuad }
        }
        onClicked: Jmain.closeNewUser();
    }

    // Standard toolbar
    Item {
        id: toolbar

        width: appItem.width
        height: appItem.height * Jmain.appToolBar;
        anchors.bottom: appItem.top
        opacity: 1
        state: "Hide"

        Framework.Loader {
            id: toolbarLoader

            width: parent.width; height: parent.height
            fontPoints: Geometry.getFontPoints();
            fieldHeight: Geometry.getFieldHeight() + Geometry.getFieldSpacing();
            fieldSpacing: Geometry.getFieldSpacing();
            theme: appItem._theme;
            obj: "" // "ToolBar"
            onBtn1click: Jmain.toolbarButtonHome();
            onBtn2click: Jmain.toolbarButtonMap();
            onBtn3click: Jmain.toolbarButtonInfo();
        }

        states: [
            State {
                name: "Show"
                AnchorChanges { target: toolbar;
                    anchors.top: appTopBanner.bottom
                    anchors.bottom: undefined }
            },
            State {
                name: "Hide"
                AnchorChanges { target: toolbar;
                    anchors.bottom: appItem.top
                anchors.top: undefined }
            }
        ]

        // The states transition are defined reversible to be reused to show and hide the object
        transitions: [
            Transition {
                from: "Show"; to: "Hide"
                reversible: true
                    AnchorAnimation { easing.type: Easing.InQuad; duration: Jmain.animDuration; }
            }
        ]
    }

    // Top banner.
    Item {
        id: appTopBanner

        width: parent.width; // Width should be always all the appItem size
        height: Math.round(parent.height * Jmain.appTopBanner) // Height is the percentage dedicated to the banner
        anchors.top: parent.top

        Framework.Loader {
            id: topbannerLoader; width: parent.width; height: parent.height
            theme: appItem._theme;
            obj_color: Jmain.appBackground; obj: "" // "StaticBanner"
        }

        MouseArea {
            id: mouseArea
            anchors.fill: parent
            onClicked: {
                if (toolbar.state == "Hide")
                    toolbar.state = "Show";
                else
                    toolbar.state = "Hide";
        }
    }
}

    // Main choice bottom buttons
    Row {
        id: basebuttons
        width: parent.width; height: Geometry.getBigButtonHeight();
        visible: true
        anchors.bottom: parent.bottom

        /*
         The button is always shown as part of the graphic interface
         Thus it become "sensible" - reacting to the click events -
         only when the text content is not an empty string.
         */
        PriceMyHouse.ButtonMain {
            id: btnAccept
            height: parent.height
            width: parent.width / 2
            side: 'Left';
            operation: appItem._mainbtntxt2
            onClicked: {
                if (operation != "")
                    Jmain.setProgramState();
            }
        }

        // Closes the program and exit
        PriceMyHouse.ButtonMain {
            id: btnExit
            height: parent.height
            width: parent.width / 2
            side: 'Right';
            operation: appItem._mainbtntxt1
            onClicked: { Qt.quit(); }
        }
    }

    // Form Navigation Buttons
    Row {
        id: navButtons

        width: parent.width;
        height: Geometry.getBigButtonHeight();
        spacing: Geometry.getButtonSpacing();
        anchors.bottom: parent.bottom;
        visible: false

        Framework.Loader {
            id: left
            width: Math.round(parent.width * 0.20)
            height: parent.height
            fontPoints: Geometry.getFontPoints();
            theme: appItem._theme;
            obj: "" // "ButtonIcon";
            obj_string: formsprofile.pageLeft
            obj_icon: JTheme.getPrevBtnIco("PMH");
            onClicked: { formsprofile.move_leftPage(); }
        }

        Framework.Loader {
            id: showAll
            width: Math.round(parent.width * 0.60) - (Geometry.getButtonSpacing() * 2)
            height: parent.height
            fontPoints: Geometry.getFontPoints();
            theme: appItem._theme;
            obj: "" // "Button";
            obj_string: formsprofile._centerNavBtn
            onClicked: { formsprofile.show_hideSummary(); }
        }

        Framework.Loader {
            id: right
            width: Math.round(parent.width * 0.20)
            height: parent.height
            fontPoints: Geometry.getFontPoints();
            theme: appItem._theme;
            obj: "" // "ButtonIcon";
            obj_string: formsprofile.pageRight
            obj_icon: JTheme.getNextBtnIco("PMH");
            onClicked: { formsprofile.move_rightPage(); }
        }
    }

    // load splash
    Framework.ShowSplash {
        id: splashappItem
        width: parent.width; height: parent.height
        customSplash: "themes/PMH/Splash.qml"
        slpashAnimDuration: Jmain.animSplash;
        waitDuration: Jmain.waitSplash;
    }
}
